package com.xyz.educenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xyz.frame.security.common.bo.UserInfoInTokenBO;
import com.xyz.frame.security.common.enums.SysTypeEnum;
import com.xyz.frame.security.common.manager.TokenStore;
import com.xyz.frame.security.common.vo.TokenInfoVO;
import com.xyz.utils.JwtUtil;
import com.xyz.utils.MD5;
import com.xyz.educenter.entity.UcenterMember;
import com.xyz.educenter.entity.vo.LoginVo;
import com.xyz.educenter.entity.vo.RegisterVo;
import com.xyz.educenter.entity.vo.UserInfoVo;
import com.xyz.dao.UcenterMemberMapper;
import com.xyz.educenter.service.UcenterMemberService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyz.exceptionhandler.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;

import static net.sf.jsqlparser.util.validation.metadata.NamedObject.user;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author zsr
 * @since 2021-06-19
 */
@Service
public class UcenterMemberServiceImpl extends ServiceImpl<UcenterMemberMapper, UcenterMember> implements UcenterMemberService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private String[] sysKeyType = {"mobile", "email"};

    /**
     * 会员登录
     *
     * @param loginVo
     * @return
     */
    @Override
    public String login(LoginVo loginVo) {
        String mobile = loginVo.getMobile();
        String password = loginVo.getPassword();
        String email = loginVo.getEmail();
        String regType = loginVo.getRegType();

        //安全校验

        if (!Arrays.asList(sysKeyType).contains(regType)) throw new BusinessException(20001, "非法篡改数据");
        boolean isMobile = regType.equals("mobile");
        //登录类型的值 手机号 或者邮箱
        String regTypeValue = isMobile ? mobile : email;

        //校验参数
        if (isMobile && StringUtils.isEmpty(mobile)) throw new BusinessException(20001, "请输入手机号");
        if (!isMobile && StringUtils.isEmpty(email)) throw new BusinessException(20001, "请输入邮箱");
        if (StringUtils.isEmpty(password)) throw new BusinessException(20001, "请输入密码");


        //获取会员
        UcenterMember member = baseMapper.selectOne(new QueryWrapper<UcenterMember>().eq(regType, regTypeValue));
        if (null == member)  throw new BusinessException(20001, "用户不存在");

        //校验密码
        if (!MD5.encrypt(password).equals(member.getPassword()))  throw new BusinessException(20001, "密码错误");

        //校验是否被禁用
        if (member.getIsDisabled())  throw new BusinessException(20001, "用户不存在");

        //使用JWT生成token字符串
//        String token = JwtUtil.getJwtToken(member.getId(), member.getNickname());
        UserInfoInTokenBO userInfoInToken = new UserInfoInTokenBO();
        userInfoInToken.setUserId(member.getId());
        userInfoInToken.setSysType(SysTypeEnum.ORDINARY.value());
        userInfoInToken.setEnabled(!member.getIsDisabled());
        // 存储token返回vo
        TokenInfoVO tokenInfoVO = tokenStore.storeAndGetVo(userInfoInToken);
        return tokenInfoVO.getAccessToken();
    }

    @Autowired
    private TokenStore tokenStore;
    @Override
    public String logout() {
        return "";
    }

    /**
     * 会员注册
     *
     * @param registerVo
     */
    @Override
    public void register(RegisterVo registerVo) {
        //获取注册信息，进行校验
        String nickname = registerVo.getNickname();
        String mobile = registerVo.getMobile();
        String email = registerVo.getEmail();
        String regType = registerVo.getRegType();
        String password = registerVo.getPassword();
        String code = registerVo.getCode();

        //安全校验
        if (!Arrays.asList(sysKeyType).contains(regType)) throw new BusinessException(20001, "非法篡改数据");

        boolean isMobile = regType.equals("mobile");
        //注册类型的值 手机号 或者邮箱
        String regTypeValue = isMobile ? mobile : email;
        //校验参数
        if (isMobile && StringUtils.isEmpty(mobile)) throw new BusinessException(20001, "请输入手机号");
        if (!isMobile && StringUtils.isEmpty(email)) throw new BusinessException(20001, "请输入邮箱");
        if (StringUtils.isEmpty(password)) throw new BusinessException(20001, "请输入密码");
        if (StringUtils.isEmpty(code)) throw new BusinessException(20001, "请输入验证码");

        //校验校验验证码
        //从redis获取发送的验证码
        String mobleCode = redisTemplate.opsForValue().get(regTypeValue);
        if (!code.equals(mobleCode)) throw new BusinessException(20001, "验证码错误");

        //查询数据库中是否存在相同的手机号码 or 邮箱
        Long count = baseMapper.selectCount(new QueryWrapper<UcenterMember>().eq(regType, regTypeValue));
        if (count.intValue() > 0) throw new BusinessException(20001, isMobile ? "该手机号已注册" : "该邮箱已注册");

        //添加注册信息到数据库
        UcenterMember member = new UcenterMember();
        member.setNickname(nickname);
        member.setMobile(registerVo.getMobile());
        member.setEmail(registerVo.getEmail());
        member.setPassword(MD5.encrypt(password));
        member.setIsDisabled(false);
        member.setAvatar("http://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83eoj0hHXhgJNOTSOFsS4uZs8x1ConecaVOB8eIl115xmJZcT4oCicvia7wMEufibKtTLqiaJeanU2Lpg3w/132");
        this.save(member);
    }

    @Override
    public UserInfoVo getLoginInfo(String memberId) {
        memberId = "1";
        UcenterMember member = baseMapper.selectById(memberId);
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(member, userInfoVo);
        return userInfoVo;
    }

    /**
     * 根据微信openId查询用户
     * @param openid 微信openId
     * @return
     */
    @Override
    public UcenterMember getByOpenid(String openid) {
        QueryWrapper<UcenterMember> wrapper=new QueryWrapper<>();
        wrapper.eq("openid",openid);
        UcenterMember member = this.getOne(wrapper);
        return member;
    }

    @Override
    public Integer countRegisterByDay(String day) {
        return baseMapper.selectRegisterCount(day);
    }
}
